今天要來說一下如何建立自定義Theme, Material 3
的主題設定這個有提供網站式的主題預覽設定,並在選擇完自訂的主題顏色、字體、按鈕樣式之後輸出成指定的檔案。
這邊附上主題建構器的網站:Material Theme Builder
這個網站提供了兩種方式,一種是 Dynamic
、另一種是 Custom
,Dynamic
是已經預設好的主題樣式,而 Custom
則是自己動手去選擇喜歡的顏色組成
以上選擇完成後需要輸出成在Android中使用的檔案,需要再右上角的地方點選Export按鈕,之後會出現以下的選項,這邊我是 JetpackCompose(Theme.kt)
,點選後會載成壓縮檔,當中會包含了Theme.kt
和Color.kt
這兩個檔案。
這邊大部分預設位置都在C:
的User資料夾中的AndroidStudioProject
,接著只要找到你要存放的位置就好了,在ui.theme
資料夾內的檔案名稱如:圖2
,當按下解壓縮後會提示您是否要覆蓋原有的檔案,這邊我是選擇覆蓋。
這邊將最頂部的package進行更改:
原本的名稱應為com.example.compose
,這邊要改成:com.example.compose_materialtest.ui.theme
,這邊的名稱會依照自己命名的專案名稱有所改變,如下所示樣式:
package com.example.compose_materialtest.ui.theme
// ...import檔案省略
這邊同理也是將Package的位置改成com.example.compose_materialtest.ui.theme
,與Theme.kt一樣會依照各自命名的專案名稱有所不同,如下所示:
package com.example.compose_materialtest.ui.theme
import androidx.compose.ui.graphics.Color
// ...Color顏色設定省略
再次回到主程式更改成主題顏色
@Composable
private fun BottomNavigation(modifier: Modifier = Modifier, context:Context) {
val resources = context.resources
NavigationBar(
modifier = modifier,
containerColor = MaterialTheme.colorScheme.surface,
contentColor = MaterialTheme.colorScheme.onSurface,
) {
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Default.Home,
contentDescription = null
)
},
label = {
Text(
text = stringResource(R.string.bottom_navigation_home)
)
},
selected = true,
onClick = {
Log.e(TAG, "SootheBottomNavigation: Home" )
Toast.makeText(context, "Home", Toast.LENGTH_SHORT).show()
},
colors = NavigationBarItemDefaults.colors(
selectedIconColor = MaterialTheme.colorScheme.secondary,
selectedTextColor = MaterialTheme.colorScheme.secondary,
unselectedIconColor = MaterialTheme.colorScheme.tertiary,
unselectedTextColor = MaterialTheme.colorScheme.tertiary
)
)
// ...其餘NavigationBarItem一樣。
}
}
@Composable
fun GreetingMessage(greetingMes: String, greetName:String) {
// 如果想在重組後保留狀態,請使用 remember「記住」可變動狀態。
val expanded = remember {mutableStateOf(false)}
val extraPadding = if (expanded.value) 72.dp else 0.dp
Column(modifier = Modifier.padding(24.dp).background(MaterialTheme.colorScheme.onBackground)) {
Row(modifier = Modifier
.padding(bottom = extraPadding)
.background(color = MaterialTheme.colorScheme.onBackground)
){
Text(text = greetingMes, Modifier
.align(androidx.compose.ui.Alignment.Top)
.padding(5.dp)
.weight(4f), color = MaterialTheme.colorScheme.background)
Text(text = greetName, modifier = Modifier
.align(androidx.compose.ui.Alignment.CenterVertically)
.padding(5.dp)
.weight(1f), color = MaterialTheme.colorScheme.background)
}
ElevatedButton(onClick = {
Log.e("ElevatedButton", "GreetingMessage: " )
expanded.value =! expanded.value
},Modifier.background(MaterialTheme.colorScheme.onBackground), shape = MaterialTheme.shapes.extraLarge) {
Text(if (expanded.value) "簡略" else "詳細")
}
}
}
@Composable
fun GreetingBackground(){
val image = painterResource(id = R.drawable.ic_launcher_foreground)
Box(modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)) {
Column (Modifier.padding(10.dp)){
Icon(
imageVector = Icons.Default.Star,
contentDescription = null,
Modifier
.align(androidx.compose.ui.Alignment.CenterHorizontally)
.padding(12.dp)
)
GreetingMessage(
greetingMes = "ITHome鐵人賽第15屆_Day16 Compose底部導覽條說明",
greetName = "Jay"
)
}
}
}
到這邊透過預覽可能會發現沒有改變,這是因為在Theme.kt的檔案中的這個函式需要被呼叫才能有深淺主題顏色的變動。
@Composable
fun AppTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable() () -> Unit
) {
val colors = if (!useDarkTheme) {
LightColors
} else {
DarkColors
}
MaterialTheme(
colorScheme = colors,
content = content
)
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// 將原本的主題改成Theme.kt中的這個函式
AppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
// 使用Scaffold將底部欄位的參數設為剛剛建立的導覽條函式
Scaffold(
bottomBar = { BottomNavigation(context = this) }
){padding ->
GreetingBackground()
}
}
}
}
}
}
// 預覽程式碼
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
val context = LocalContext.current // 獲取context在Preview中顯示
// 以下這個改成AppTheme就能修改後的主題顯示預覽了
AppTheme {
Scaffold(
bottomBar = { BottomNavigation(context = context) }
){padding ->
GreetingBackground()
}
}
}
以上就完成了今天的主題顏色變更操作了,下面來看一下各個主題下的顏色變動。
使用這個的好處就是有區分深色主題與淺色主題的顏色設定,而這個設定判斷是已經在Theme.kt
檔案中幫你設定好了,不需要我們再去做判斷及調整。
以上是今天對於JetpackCompose中的自訂義主題的說明與實際操作。